home *** CD-ROM | disk | FTP | other *** search
- /*
- * temperature manager control strip module
- * based on: ControlStripSample.c,a sample Control Strip module © by macDTS '93
- * melt algorithm ideas by Benoit Schillings
- * melt implementation by Dave Blundell
- * control strip by Brian Gaeke
- */
-
- #include <Icons.h>
- #include <ControlStrip.h>
- #include "temp_cs.h"
- #include <A4Stuff.h>
- #include <math.h>
- #include <LowMem.h>
- #include <stdio.h>
- #include <Notification.h>
- #include "layermgr.h"
- #define PI 3.1415926535897932384626499
-
-
- //////////////////////////////////////////////////////////////////////////////////////////////
- //
- // global variables
-
- typedef struct Globals { // global variables we use while we exist
- Handle thermoIcon; // handle to thermo icon
- PicHandle popupArrowPicture; // picture to show we have a popup menu
- Handle helpStrings; // balloon help strings for each state
- short helpStringIndex; // which help string to display
- short whichIcon; // which icon we're drawing
- MenuHandle configMenu; // menu to select display options
- short level; // current thermo value
- short goingdown;
- unsigned long lasttime;
- short didNot;
- NMRec currNotReq;
- Str255 happystring;
- } Globals;
-
-
- //////////////////////////////////////////////////////////////////////////////////////////////
- //
- // information saved across restarts
-
- typedef struct SavedSettings {
- OSType signature; // signature to verify it's for this module
- short whichIcon; // which icon we're drawing
- } SavedSettings;
-
-
- //////////////////////////////////////////////////////////////////////////////////////////////
- //
- // prototypes
-
- long Initialize();
- void CleanUp(Globals **globs);
- void DrawThermo(Globals *gb, Rect *statusRect);
- void GetCurrentIcon(Globals *gb);
- long HandleMouseClick(Globals *gb, Rect *statusRect);
- short SavePreferences(Globals *gb);
- int do_shift(const int numpix, const int numrows);
- Boolean IsWholeScreen(WindowPeek wl);
- WindowPtr GetWindowToMelt(void);
- void PostStrNotification(Globals *gb,short rsrcId, short index);
- void IdleCall(Globals *gb);
-
- /* Dave's and Benoit's Melt Algorithm.
- *
- * do_shift uses getpixelXY and putpixelXY to move pixels in the melting image.
- * numpix is the number of pixels across; numrows is the number of rows down.
- * as a precondition, the port is set to the port we are melting.
- * the pen color doesn't matter.
- */
- int do_shift(const int numpix, const int numrows)
- {
- float sinvalue,val2,radians,increment,prob;
- int curpix,currow,tmprow,shift,drift, loopy, *ripple;
- RGBColor color,test,test2,test3,test4;
- const RGBColor white = {0xffff, 0xffff, 0xffff};
- PatHandle dpat = GetPattern(16);
- Pattern black;
- int whee;
- for (whee=0; whee<8; whee++) { black.pat[whee] = 0xffff; }
- DetachResource((Handle)dpat);
- HLock((Handle)dpat);
- radians=0;
-
- for(currow=0; currow<numrows; currow+=2) /* for every rom in the window.... */
- {
- radians=Random()/1369; /* herm. this could be done better. it currently puts a weird seed in radians to */
- radians=fmod(radians,2*PI); /* minimize a sine wave appearance. it doesnt work. TABLE */
-
- for(curpix=0; curpix<numpix; curpix+=3) /* for every pixel in each row...*/
- {
-
- GetCPixel(curpix,currow,&color);
- if(curpix+1 < numpix) {
- GetCPixel(curpix+1,currow,&test);
- if(curpix+2 < numpix) {
- GetCPixel(curpix+2,currow,&test2);
- if(curpix+3 < numpix) {
- GetCPixel(curpix+3,currow,&test3); }
- else {
- GetCPixel(curpix+2,currow,&test3); }
- }
- else { GetCPixel(curpix+1,currow,&test2); }
- }
- else { GetCPixel(curpix,currow,&test); } /* this big ugly nested if .. else statement block basicaly makes */
- /* sure we are still inside the window to avoid acquiring BlacTar(tm) from GetCPixel returning 0 from */
- /* offscreen data */
-
- /* find hte "average color" of our dripping pixels */
- color.red=((float)0.25*color.red)+((float)0.25*test.red)+((float)0.25*test2.red)+((float)0.25*test3.red);
- color.blue=((float)0.25*color.blue)+((float)0.25*test.blue)+((float)0.25*test2.blue)+((float)0.25*test3.blue);
- color.green=((float)0.25*color.green)+((float)0.25*test.green)+((float)0.25*test2.green)+((float)0.25*test3.green);
-
- if(color.red != white.red && color.blue != white.blue && color.green != white.green) /* are we white? */
- {
- sinvalue = 4 * sin(radians);
- sinvalue+= 3 * sin(radians + (float)(PI/4));
- sinvalue+= 2 * sin(radians + (float)(PI/2.5));
- sinvalue+= 1 * sin(radians + (float)(PI / 1.5));
- radians+= 40 * PI / numpix;
- radians=fmod(radians,2*PI);
- sinvalue=fabs(sinvalue);
-
- sinvalue = (float)(currow/2) + (5 * sinvalue); /* this piece of magic code contains many magic numbers */
- /* it seems to generate the number of pixels that the piece drips */
-
- for(loopy=0;loopy<sinvalue;loopy++)
- {
-
- GetCPixel(curpix,currow+loopy,&test);
- if(curpix+1 < numpix)
- {
- GetCPixel(curpix+1,currow+loopy,&test2);
- if(curpix+2 < numpix)
- {
- GetCPixel(curpix+2,currow+loopy,&test3);
- if(curpix+3 < numpix)
- {
- GetCPixel(curpix+3,currow+loopy,&test4);
- }
- else { GetCPixel(curpix+2,currow+loopy,&test4); }
- }
- else { GetCPixel(curpix+1,currow+loopy,&test3); }
- }
- else { GetCPixel(curpix,currow+loopy,&test2); }/* this nasty whore makes sure we dont read from */
- /* a part of the windows that doesnt **REALLY** exist */
-
- /* get the average color of hte pixel about to be dripped on using averages of surrounding pixels. */
- test.red=(0.25*test4.red)+(0.25*test.red)+(0.25*test2.red)+(0.25*test3.red);
- test.blue=(0.25*test4.blue)+(0.25*test.blue)+(0.25*test2.blue)+(0.25*test3.blue);
- test.green=(0.25*test4.green)+(0.25*test.green)+(0.25*test2.green)+(0.25*test3.green);
-
-
- test.red= (0.8*test.red) + (color.red*0.2); /* FUDGE ME!@!@!@!@!@!@!@! */
- test.blue= (0.8*test.blue) + (color.blue*0.2); /* controls how much original/fripped color is used */
- test.green= (0.8*test.green) + (color.green*0.2); /* FUDGE ME @!@!@!@!@!@ */
-
- #ifdef USERECTS
- Rect rect;
- rect.top = currow+loopy;
- rect.left = curpix;
- rect.bottom = rect.top + 1;
- rect.right = curpix+2;
- RGBForeColor(&test);RGBBackColor(&test);
- FillRect(&rect,&qd.black);
- #else
- SetCPixel(curpix,currow+loopy,&test); /* OPTIMIZE ME!@!@! */
- SetCPixel(curpix+1,currow+loopy,&test);/* OPTIMIZE ME!@!@! */
- SetCPixel(curpix+2,currow+loopy,&test);/* OPTIMIZE ME!@!@! */
-
- SetCPixel(curpix,currow+loopy+1,&test); /* OPTIMIZE ME!@!@! */
- SetCPixel(curpix+1,currow+loopy+1,&test);/* OPTIMIZE ME!@!@! */
- SetCPixel(curpix+2,currow+loopy+1,&test);/* OPTIMIZE ME!@!@! */
- #endif
- }
-
- }
-
- tmprow=currow-4; /* generate wavy top.... perterbance TURN ME INTO A TABLE LOOKUP !@!@! */
- tmprow-=2*sin(curpix/4); /* generate wavy top.... perterbance TURN ME INTO A TABLE LOOKUP !@!@! */
-
- SetCPixel(curpix,tmprow-3,&white); /* OPTIMIZE ME!@!@! */
- SetCPixel(curpix+1,tmprow-3,&white);/* OPTIMIZE ME!@!@! */
- SetCPixel(curpix+2,tmprow-3,&white);/* OPTIMIZE ME!@!@! */
-
- SetCPixel(curpix,tmprow-4,&white); /* OPTIMIZE ME!@!@! */
- SetCPixel(curpix+1,tmprow-4,&white);/* OPTIMIZE ME!@!@! */
- SetCPixel(curpix+2,tmprow-4,&white);/* OPTIMIZE ME!@!@! */
- /* erase what we have left behind */
-
- }
- PenPat(*dpat);
- PenSize(3,3);
- MoveTo(0,currow-5);
- LineTo(numpix,currow-5);
- PenPat(&black);
- if (Button()) { return(0); } /* for now, click to leave */
- }
- DisposeHandle((Handle)dpat);
- }
-
- void PostStrNotification(Globals *gb,short rsrcId, short index)
- {
- OSErr err;
-
- //DebugStr("\pnotification.");
- #if 0
- GetIndString(gb->happystring,rsrcId, index);
-
- gb->currNotReq.qType = 8;
- gb->currNotReq.nmSound = (Handle)-1L;
- gb->currNotReq.nmStr = gb->happystring;
- err = NMInstall(&gb->currNotReq);
- if (err) {
- SysBeep(1);
- }
- #endif
- }
-
- void IdleCall(Globals *gb)
- {
- unsigned long nowtime;
- GetDateTime(&nowtime);
- if (nowtime - gb->lasttime > 75) {
- gb->level++;
- gb->lasttime = nowtime;
- }
- switch(gb->level) {
- case 2:
- if (gb->didNot < 3) {
- PostStrNotification(gb,257,0);
- gb->didNot = 3;
- }
- break;
- case 4:
- if (gb->didNot < 5) {
- PostStrNotification(gb,257,1);
- gb->didNot = 5;
- }
- break;
- case 6:
- if (gb->didNot < 7) {
- PostStrNotification(gb,257,2);
- gb->didNot = 7;
- }
- break;
- }
- }
-
-
- //////////////////////////////////////////////////////////////////////////////////////////////
- //
- // entry point
-
- pascal long main(unsigned long message, Globals **globs, Rect *statusRect, GrafPtr statusPort) {
- char savedState;
- Globals *gb;
- long result;
- Handle theLastIcon;
- Str255 helpString;
-
- EnterCodeResource();
-
- if ((long)globs > 0) { // if we have globals allocated,
- savedState = HGetState((Handle)globs); // save the locked/unlocked state,
- HLock((Handle)globs); // lock the handle to the globals,
- gb = *globs; // and point to the globals directly
- }
-
- result = 0; // just return zero for unknown messages
- switch(message) {
- case sdevInitModule: // initialize the module
- if ((result = Initialize()) > 0) break; // and exit if successful
- globs = (Globals **)result;
-
- case sdevCloseModule: // clean up before being closed
- CleanUp(globs);
- globs = 0L;
- break;
-
- case sdevFeatures: // return feature bits
- result = (1<<sdevWantMouseClicks) |\
- (1<<sdevDontAutoTrack) |\
- (1<<sdevHasCustomHelp);
- break;
-
- case sdevGetDisplayWidth: // return display width
- //result = (SmallIconWidth/2) +
- // SBGetBarGraphWidth(8) + kSlop;
- result = SmallIconWidth;
- break;
-
- case sdevPeriodicTickle: // periodic tickle when nothing else is happening
- //theLastIcon = gb->lastIcon; // save the last state
- //GetCurrentIcon(gb); // update everything
- //if (theLastIcon == gb->lastIcon) break; // if everything's the same, just exit
- //result += 1<<sdevHelpStateChange; // flag a state change in case we're displaying help
-
- //statusRect->right = statusRect->left + IconWidth;
- //EraseRect(statusRect); // erase the icon
-
- /* May be wanting to do timing related melt stuff triggered from here. BRG */
- IdleCall(gb);
- break;
-
- case sdevDrawStatus: // update the interface in the Control Strip
- DrawThermo(gb, statusRect);
- break;
-
- case sdevMouseClick: // user clicked on the module's display area in the Control Strip
- result = HandleMouseClick(gb, statusRect);
- break;
-
- case sdevSaveSettings: // save changed settings
- //result = SavePreferences(gb);
- break;
-
- case sdevShowBalloonHelp: // display custom balloon help
- SBGetDetachedIndString(helpString, gb->helpStrings, 0);
- SBShowHelpString(statusRect, helpString);
- break;
- }
-
- if ((long)globs > 0) // if we have globals allocated,
- HSetState((Handle)globs, savedState); // restore the locked/unlocked state
-
- ExitCodeResource();
- return(result);
- }
-
-
- //////////////////////////////////////////////////////////////////////////////////////////////
- //
- // initializes the module
-
- long Initialize() {
- short i;
- long result;
- Globals **globs, *gb;
- Str255 prefsResourceName;
- SavedSettings **preferences;
- Handle *theIconSuite;
-
- result = -1; // assume failure
-
- if (! (globs = (Globals **)NewHandleClear(sizeof(Globals))))
- return(MemError()); // allocate the globals
-
- HLock((Handle)globs); // lock the globals while using them
- gb = *globs; // and get a pointer to them
-
-
- result = SBGetDetachIconSuite(&gb->thermoIcon, ThermoID, svAllSmallData);
- if (result != noErr) { goto done; }
- #if 0
- // load and detach the ‘up arrow’ picture
-
- if (! (gb->popupArrowPicture = GetPicture(PopupArrowPictID))) goto done;
- DetachResource((Handle)gb->popupArrowPicture);
-
- // load and detach the configuration menu
-
- if (! (gb->configMenu = GetMenu(ConfigMenuID))) goto done;
- DetachResource((Handle)gb->configMenu);
- #endif
-
- // load and detach the help strings
-
- if (! (gb->helpStrings = Get1Resource('STR#', HelpStringsID))) goto done;
- DetachResource(gb->helpStrings);
- // get the module's saved preferences, if any, and configure the module
-
- //gb->whichIcon = mShowFirstIcon;
- /*SBGetDetachedIndString(prefsResourceName, gb->helpStrings, sPrefResourceName);
- if (! SBLoadPreferences(prefsResourceName, (Handle *)&preferences) &&
- ((**preferences).signature == 'Samp'))
- gb->whichIcon = (**preferences).whichIcon;
- */
- //GetCurrentIcon(gb); // initialize which icon to draw
- gb->level = 1; gb->goingdown = 1;
- GetDateTime(&gb->lasttime);
- gb->didNot =0;// no notifications done yet.
-
- HUnlock((Handle)globs); // unlock the globals
-
- result = (long)globs; // return the handle to the globals as the result
-
- done:
- return(result); // return either a handle or an error code
- }
-
-
- //////////////////////////////////////////////////////////////////////////////////////////////
- //
- // disposes of our storage before we get closed
-
- void CleanUp(Globals **globs) {
- Globals *gb;
-
- if ((long)globs <= 0) return;
-
- HLock((Handle)globs);
- gb = *globs;
-
- if (gb->thermoIcon) DisposeIconSuite(gb->thermoIcon, true);
- if (gb->configMenu) DisposeMenu(gb->configMenu);
- if (gb->helpStrings) DisposeHandle(gb->helpStrings);
-
- DisposeHandle((Handle)globs);
- }
-
-
- //////////////////////////////////////////////////////////////////////////////////////////////
- //
- // draws the current icon and thermometer.
-
- void DrawThermo(Globals *gb, Rect *statusRect)
- {
- // short arrowHeight;
- Rect iconRect;
- Point topLeft;
- // draw the current icon
- iconRect = *statusRect;
- iconRect.right = SmallIconWidth+iconRect.left;
- (void) PlotIconSuite(&iconRect, atNone, ttNone, gb->thermoIcon);
- //topLeft.h = iconRect.right - (SmallIconWidth/2) + kSlop;
- //topLeft.v = iconRect.top;
- //SBDrawBarGraph(gb->level,MaxLevel,BarGraphSlopeRight,topLeft);
-
- // draw an ‘up arrow’ to show that the module has a popup menu
- /*
- arrowHeight = (**gb->popupArrowPicture).picFrame.bottom - (**gb->popupArrowPicture).picFrame.top;
- statusRect->left = statusRect->right;
- statusRect->right += (**gb->popupArrowPicture).picFrame.right - (**gb->popupArrowPicture).picFrame.left;
- statusRect->top = (statusRect->top + statusRect->bottom - arrowHeight) >> 1;
- statusRect->bottom = statusRect->top + arrowHeight;
- DrawPicture(gb->popupArrowPicture, statusRect);*/
- }
-
-
- //////////////////////////////////////////////////////////////////////////////////////////////
- //
- // stuffs the icon suite handle of the current icon into gb->lastIcon,
- // and the related help STR# index into gb->helpStringIndex
- #if 0
- void GetCurrentIcon(Globals *gb) {
-
- switch (gb->whichIcon) {
- case mShowFirstIcon:
- gb->lastIcon = gb->firstIcon;
- gb->helpStringIndex = sFirstIconHelp;
- break;
-
- case mShowSecondIcon:
- gb->lastIcon = gb->secondIcon;
- gb->helpStringIndex = sSecondIconHelp;
- break;
-
- case mShowThirdIcon:
- gb->lastIcon = gb->thirdIcon;
- gb->helpStringIndex = sThirdIconHelp;
- break;
- }
- }
- #endif
-
- #if 0
- Boolean IsWholeScreen(WindowPeek wl)
- {
- WindowPtr wp = (WindowPtr)wl;
- Rect foo;
- GDHandle gdh = GetMainDevice();
- int foowidth, screenwidth;
- int fooheight, screenheight;
- Boolean result;
- char buf[255];
-
- foo = wp->portRect;
- foowidth = foo.right - foo.left;
- fooheight = foo.bottom - foo.top;
- screenwidth = (*gdh)->gdRect.right - (*gdh)->gdRect.left;
- screenheight = (*gdh)->gdRect.bottom - (*gdh)->gdRect.top;
-
- result = !((foowidth < screenwidth) || (fooheight < screenheight));
-
- sprintf(buf,"%dx%d being considered as %s the whole screen (%dx%d)",foowidth,fooheight,
- result ? "being" : "not being", screenwidth,screenheight);
- DebugStr(CtoPstr(buf));
- return result;
- }
- #endif
- WindowPtr GetWindowToMelt(void)
- {
- /* Pray. */
- LayerPtr f;
- WindowPeek wl;
- char buf[255];
- f = GetFirstLayer(); /* First layer is the Control Strip layer. */
- //sprintf(buf,"first layer is 0x%lx, control strip, ignoring.",f);
- //DebugStr(CtoPstr(buf));
- for (; f; f = GetNextLayer(f)) {
- //sprintf(buf,"next layer is 0x%lx.",f);
- //DebugStr(CtoPstr(buf));
- wl = (WindowPeek)GetFirstLayerWindow(f);
- //sprintf(buf,"1st window (layer 0x%lx) is 0x%lx, %s visible, %s hilited.",f,wl,
- // wl->visible ? "is" : "not", wl->hilited ? "is" : "not");
- //DebugStr(CtoPstr(buf));
- for (; wl; wl = wl->nextWindow) {
- //sprintf(buf,"next window (layer 0x%lx) is 0x%lx, %s visible, %s hilited.",f,wl,
- //wl->visible ? "is" : "not", wl->hilited ? "is" : "not");
- //DebugStr(CtoPstr(buf));
- if (wl->refCon == 'sdev') {
- return (WindowPtr)wl;
- }
- }
- }
- return (WindowPtr)NULL;
- }
-
-
- //////////////////////////////////////////////////////////////////////////////////////////////
- //
- // handles a mouse click on the module's display by tracking a popup menu to change settings
-
- long HandleMouseClick(Globals *gb, Rect *statusRect) {
- short menuItem;
- long result=0;
- short itemHit;
- #if 0
- menuItem = SBTrackPopupMenu(statusRect, gb->aboutMenu);
- // call the utility routine to display a popup menu
- CheckItem(gb->configMenu, gb->whichIcon, false);// uncheck the item for the previous icon
-
- result = 0;
- if ((menuItem > 0) && (menuItem != gb->whichIcon)) {
- // if something was selected,
- gb->whichIcon = menuItem; // save the menu item number,
- result = 1<<sdevNeedToSave; // and notify the Control Strip that we need to update preferences
- }
- /* This is going away. */
- if (gb->goingdown) {
- gb->level--;
- if (gb->level == 0) {
- gb->goingdown = 0;
- }
- } else {
- gb->level++;
- if (gb->level == MaxLevel -1) {
- gb->goingdown++;
- }
- }
-
- if (gb->level == MaxLevel -1)
- #endif
- GrafPtr savePort = NULL;
- WindowPtr frontWind = FrontWindow();
- RgnHandle saveClip = NewRgn();
- int height;
- int width;
- char buf[512];
- DialogPtr dl = NULL;
-
- //Debugger();
- //dl=GetNewDialog(256,NULL,(void *)-1L);
- //if (!dl) return 0;
- //do { SBModalDialogInContext(NULL, &itemHit); } while (itemHit != 1 && itemHit != 2);
- //DisposeDialog(dl);
- //if (itemHit != 1) return 0;
-
- if (!frontWind) {
- frontWind = LMGetWMgrPort();
- if (!frontWind) {
- return 0;
- }
- }
- height = frontWind->portRect.bottom - frontWind->portRect.top;
- width = frontWind->portRect.right - frontWind->portRect.left;
- //sprintf(buf,"Now ready to melt. frontWind=%lx savePort=%lx saveClip=%lx %dx%d",
- // frontWind,savePort,saveClip,width,height);
- //DebugStr(CtoPstr(buf));
- GetPort(&savePort);
- SetPort(frontWind);
- GetClip(saveClip);
- ClipRect(&frontWind->portRect);
- do_shift(width,height+8);
- SetClip(saveClip);
- SetPort(savePort);
- DisposeRgn(saveClip);
- SBShowHideControlStrip(false);
- return(result);
- }
-
-
- //////////////////////////////////////////////////////////////////////////////////////////////
- //
- // saves the module's settings so they'll be available across restarts
-
- short SavePreferences(Globals *gb) {
- short result;
- SavedSettings **preferences;
- Str255 prefsResourceName;
-
- preferences = (SavedSettings**)NewHandle(sizeof(SavedSettings));
- if (! (result = MemError())) { // allocate a block to hold the settings
-
- (**preferences).signature = 'Samp'; // include a signature to verify it's ours
- (**preferences).whichIcon = gb->whichIcon; // stuff in the menu item number of the current icon
-
- SBGetDetachedIndString(prefsResourceName, gb->helpStrings, sPrefResourceName);
- // get the name of the preferences resource
- result = SBSavePreferences(prefsResourceName, (Handle)preferences);
- // save the settings in the Control Strip's preferences file
-
- DisposeHandle((Handle)preferences); // get rid of the block
- }
-
- return(result);
- }
-